using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Text;

using HumanElement.Xna.Construct.GameState.MenuItems;
using System.Windows.Forms;
using System.Drawing.Design;

using HumanElement.Xna.Construct.GameState.MenuItems;

namespace HumanElement.Xna.Construct.GameState.Design
{
    [ToolboxItemFilter("Ferpect.GameState.MenuItem", ToolboxItemFilterType.Require)]
    public class MenuScreenDesigner : ViewDocumentDesigner<MenuScreen>
    {
        private MenuScreenControl menuScreenControl;
        private IDesignerHost host;
        private ISelectionService selectionService;

        public override void Initialize(IComponent component)
        {
            this.menuScreenControl = (MenuScreenControl)component;
            base.Initialize(component);

            this.host = (IDesignerHost)this.GetService(typeof(IDesignerHost));
            IComponentChangeService componentChangeService = (IComponentChangeService)this.GetService(typeof(IComponentChangeService));
            if (componentChangeService != null)
            {
                componentChangeService.ComponentAdded += new ComponentEventHandler(this.OnComponentAdded);
                componentChangeService.ComponentRemoved += new ComponentEventHandler(this.OnComponentRemoved);
                componentChangeService.ComponentChanged += new ComponentChangedEventHandler(this.OnComponentChanged);
            }
            this.selectionService = (ISelectionService)this.GetService(typeof(ISelectionService));

            this.menuScreenControl.Click += new EventHandler(OnMenuScreenControlClick);
            this.menuScreenControl.DoubleClick += new EventHandler(OnMenuScreenControlDoubleClick);

            //INestedContainer nestedContainer = (INestedContainer)this.GetService(typeof(INestedContainer));
            //nestedContainer.Add(this.menuScreenControl.Component);
            this.host.LoadComplete += new EventHandler(OnHostLoadComplete);
        }

        void OnHostLoadComplete(object sender, EventArgs args)
        {
            try
            {
                this.menuScreenControl.Component.Initialize();
            }
            catch (Exception)
            {
                //TODO: Report error.
                //Note: We handle this exception here so that the designer will be displayed.
            }

            IToolboxService toolboxService = (IToolboxService)this.GetService(typeof(IToolboxService));

            //TODO: Remove this. Adding the item to the toolbox is useful for testing,
            //      but this will add a duplicate item each time the designer loads...
            ToolboxItem menuItemTool = new ToolboxItem(typeof(ToggleMenuItem));
            toolboxService.AddToolboxItem(menuItemTool);
        }

        void OnComponentChanged(object sender, ComponentChangedEventArgs args)
        {
            if (args != null && args.Member != null)
            {
                if (args.Member.Name == "BackgroundTexture" || args.Member.Name == "FontName")
                {
                    this.menuScreenControl.Component.Reinitialize();
                }
            }
        }

        /// <summary>
        /// This method determines if the control should handle mouse messages or not. If
        /// the point is over a menu item, then we return true so that the control can handle
        /// the mouse input, which will generate events for this designer to handle.
        /// </summary>
        /// <param name="pt"></param>
        /// <returns></returns>
        protected override bool GetHitTest(System.Drawing.Point pt)
        {
            System.Drawing.Point clientPt = this.menuScreenControl.PointToClient(pt);

            MenuItem item = this.menuScreenControl.MenuItemFromPoint(clientPt);
            return (item != null);
        }

        void OnMenuScreenControlClick(object sender, EventArgs args)
        {
            MouseEventArgs mouseArgs = args as MouseEventArgs;
            MenuItem item = this.menuScreenControl.MenuItemFromPoint(mouseArgs.Location);
            if (item != null)
            {
                this.selectionService.SetSelectedComponents(new object[] { item });
            }
        }

        void OnMenuScreenControlDoubleClick(object sender, EventArgs args)
        {
            MouseEventArgs mouseArgs = args as MouseEventArgs;
            MenuItem item = this.menuScreenControl.MenuItemFromPoint(mouseArgs.Location);
            if (item != null)
            {
                IDesigner itemDesigner = this.host.GetDesigner(item);
                itemDesigner.DoDefaultAction();
            }
        }
        private void OnComponentAdded(object sender, ComponentEventArgs args)
        {
            if (args != null && !this.host.Loading)
            {
                MenuItem item = args.Component as MenuItem;
                if (item != null && !this.menuScreenControl.MenuItems.Contains(item))
                {
                    this.menuScreenControl.MenuItems.Add(item);
                }
            }
        }

        private void OnComponentRemoved(object sender, ComponentEventArgs args)
        {
            if (args != null && !this.host.Loading)
            {
                MenuItem item = args.Component as MenuItem;
                if (item != null && this.menuScreenControl.MenuItems.Contains(item))
                {
                    this.menuScreenControl.MenuItems.Remove(item);
                }
            }
        }
    }
}
